package com.ocom.payhandle.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ocom.common.entity.card.EntityXfRecord;
import com.ocom.common.entity.card.EntityXfRecordProcessExxx;
import com.ocom.common.entity.pay.EntityXfRecordProcessExtend;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.DateUtil;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.pyhandle.UserOrdersQueryVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payhandle.dao.IDaoXfRecordProcessExxx;
import com.ocom.payhandle.service.XfRecordProcessExxxService;
import com.ocom.payhandle.vo.TimesAmountVoExxx;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;



@Slf4j
@Service
public class XfRecordProcessExxxServiceImpl extends JoinServiceImpl<IDaoXfRecordProcessExxx, EntityXfRecordProcessExxx> implements XfRecordProcessExxxService {

    @Autowired
    IDaoXfRecordProcessExxx iDaoXfRecordProcessExxx;

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public Result timesManJian(Long companyId, EntityXfRecord entityXfRecord) {
        try {
            List<TimesAmountVoExxx> xfRecord = this.getTimesManJian(entityXfRecord);
            Map<String, Integer> merchPayCountMap = new HashMap<>();
            if (xfRecord == null || xfRecord.size() == 0) {
                return ResultUtil.success(merchPayCountMap);
            }
            //list转map
            merchPayCountMap = xfRecord.stream().collect(Collectors.toMap(e -> e.getDiscount().toString(),
                    e -> e.getTimes(),
                    (e1, e2) -> e1));
            return ResultUtil.success(merchPayCountMap);
        } catch (Exception e) {
            log.info("请求方式:【{}】,查询的请求的数据:【{}】,异常信息:【{}】", "获取饭堂消费次数", entityXfRecord, e);
            return ResultUtil.error(ResultEnum.Err_4002);
        }
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public Result times(Long companyId, EntityXfRecord entityXfRecord) {
        try {
            TimesAmountVoExxx xfRecord = this.getTimes(entityXfRecord);
            Map<String, Object> map = new HashMap<>();
            map.put("times", xfRecord.getTimes());
            return ResultUtil.success(map);
        } catch (Exception e) {
            log.info("请求方式:【{}】,查询的请求的数据:【{}】,异常信息:【{}】", "获取饭堂消费次数", entityXfRecord, e);
            return ResultUtil.error(ResultEnum.Err_4002);
        }
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public Result xfUserparam(Long companyId, EntityXfRecord entityXfRecord) {
        try {
            TimesAmountVoExxx xfRecord = this.getxfUserparam(entityXfRecord);
            Map<String, Object> map = new HashMap<>();
            map.put("times", xfRecord.getTimes());
            if (xfRecord.getAmount() == null) {
                xfRecord.setAmount(0);
            }
            map.put("amount", xfRecord.getAmount());
            return ResultUtil.success(map);
        } catch (Exception e) {
            log.info("请求方式:【{}】,查询的请求的数据:【{}】,异常信息:【{}】", "获取饭堂消费的情况", entityXfRecord, e);
            return ResultUtil.error(ResultEnum.Err_4002);
        }
    }


    private List<TimesAmountVoExxx> getTimesManJian(EntityXfRecord entityXfRecord) {
        JoinLambdaWrapper<EntityXfRecordProcessExxx> queryWrapper = new JoinLambdaWrapper<>(EntityXfRecordProcessExxx.class);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPId, entityXfRecord.getPId());
        queryWrapper.eq(EntityXfRecordProcessExxx::getComId, entityXfRecord.getComId());
        queryWrapper.in(EntityXfRecordProcessExxx::getConsState, 1, 3, 5);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPayState, 1);
        queryWrapper.gt(EntityXfRecordProcessExxx::getDiscount, 0);
        queryWrapper.eq(EntityXfRecordProcessExxx::getIfRefund, 0);
        queryWrapper.eq(EntityXfRecordProcessExxx::getConsType, entityXfRecord.getConsType());

        if(entityXfRecord.getComId()==693l){
            queryWrapper.ne(EntityXfRecordProcessExxx::getPointId, 1015l);
        }

        if (!CommonUtil.isNull(entityXfRecord.getReserved1()) && entityXfRecord.getReserved1().equals("selectMerchTrue")) {
            queryWrapper.eq(EntityXfRecordProcessExxx::getMerchId, entityXfRecord.getMerchId());
        }
        if (!CommonUtil.isNull(entityXfRecord.getReserved2())) {
            queryWrapper.apply("find_in_set(  xf_record_process.meal_no , \"" + entityXfRecord.getReserved2() + "\" )  and xf_record_process.meal_no IS NOT NULL ");
        }

        String strDate = DateUtils.getStrDate(entityXfRecord.getConsTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);

        //餐段按天
        strDate = strDate.substring(0, 10);
        queryWrapper.eq(EntityXfRecordProcessExxx::getMealDate, strDate);

        queryWrapper.groupBy(EntityXfRecordProcessExxx::getDiscount);

        queryWrapper.notDefaultSelectAll().select(EntityXfRecordProcessExxx::getDiscount).leftJoin(EntityXfRecordProcessExtend.class, EntityXfRecordProcessExtend::getOrderId, EntityXfRecordProcessExxx::getId)
                .select(EntityXfRecordProcessExtend::getCancelState).selectAs((cb) -> {
                    cb.add(" count(*) ","times",false); // 这个为false就是代表不是字符串，会原样查询 在1.3.1版本后支持
                }).apply("( xf_record_process_extend.cancel_state = 0 or  xf_record_process_extend.cancel_state is null  ) ").end();

        return this.joinList(queryWrapper,TimesAmountVoExxx.class);
    }

    private TimesAmountVoExxx getTimes(EntityXfRecord entityXfRecord) {
        JoinLambdaWrapper<EntityXfRecordProcessExxx> queryWrapper = new JoinLambdaWrapper<>(EntityXfRecordProcessExxx.class);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPId, entityXfRecord.getPId());
        queryWrapper.eq(EntityXfRecordProcessExxx::getComId, entityXfRecord.getComId());
//        queryWrapper.eq("cons_state",1);
        if(entityXfRecord.getComId()==693l){
            queryWrapper.ne(EntityXfRecordProcessExxx::getPointId, 1015l);
        }
        queryWrapper.in(EntityXfRecordProcessExxx::getConsState, 1, 3, 5);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPayState, 1);
        queryWrapper.eq(EntityXfRecordProcessExxx::getIfRefund, 0);
        queryWrapper.eq(EntityXfRecordProcessExxx::getConsType, entityXfRecord.getConsType());

        if (!CommonUtil.isNull(entityXfRecord.getReserved1()) && entityXfRecord.getReserved1().equals("selectMerchTrue")) {
            queryWrapper.eq(EntityXfRecordProcessExxx::getMerchId, entityXfRecord.getMerchId());
        }
        if (!CommonUtil.isNull(entityXfRecord.getReserved2())) {
            queryWrapper.apply("find_in_set(  xf_record_process.meal_no , \"" + entityXfRecord.getReserved2() + "\" )  and xf_record_process.meal_no IS NOT NULL ");
        }

        String strDate = DateUtils.getStrDate(entityXfRecord.getConsTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);

        if (entityXfRecord.getMealNo().equals("500")) {
            //餐段按天
            strDate = strDate.substring(0, 10);
            queryWrapper.eq(EntityXfRecordProcessExxx::getMealDate, strDate);
        } else if (entityXfRecord.getMealNo().equals("1000")) {
            //按月查询
            strDate = strDate.substring(0, 7).replace("-", "");
            queryWrapper.eq(EntityXfRecordProcessExxx::getMonthValue, strDate);
        } else {
            if (CommonUtil.isNull(entityXfRecord.getReserved2())) {
                queryWrapper.eq(EntityXfRecordProcessExxx::getMealNo, entityXfRecord.getMealNo());
            }
            strDate = strDate.substring(0, 10);
            queryWrapper.eq(EntityXfRecordProcessExxx::getMealDate, strDate);
        }

        queryWrapper.notDefaultSelectAll().leftJoin(EntityXfRecordProcessExtend.class, EntityXfRecordProcessExtend::getOrderId, EntityXfRecordProcessExxx::getId)
                .selectAs((cb) -> {
                    cb.add(" count(*) ","times",false); // 这个为false就是代表不是字符串，会原样查询 在1.3.1版本后支持
                }).apply("( xf_record_process_extend.cancel_state = 0 or  xf_record_process_extend.cancel_state is null  ) ").end().joinList(TimesAmountVoExxx.class);

        return this.joinGetOne(queryWrapper,TimesAmountVoExxx.class);
    }

    private TimesAmountVoExxx getxfUserparam(EntityXfRecord entityXfRecord) {
        JoinLambdaWrapper<EntityXfRecordProcessExxx> queryWrapper = new JoinLambdaWrapper<>(EntityXfRecordProcessExxx.class);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPId, entityXfRecord.getPId());
        queryWrapper.eq(EntityXfRecordProcessExxx::getComId, entityXfRecord.getComId());
        queryWrapper.in(EntityXfRecordProcessExxx::getConsState, 1, 3, 5);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPayState, 1);
        queryWrapper.eq(EntityXfRecordProcessExxx::getIfRefund, 0);
        queryWrapper.eq(EntityXfRecordProcessExxx::getConsType, entityXfRecord.getConsType());
        if(entityXfRecord.getComId()==693l){
            queryWrapper.ne(EntityXfRecordProcessExxx::getPointId, 1015l);
        }
        if (entityXfRecord.getReserved1() != null && entityXfRecord.getReserved1().equals("selectMerchTrue")) {
            queryWrapper.eq(EntityXfRecordProcessExxx::getMerchId, entityXfRecord.getMerchId());
        }

        String strDate = DateUtils.getStrDate(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS);
        if (entityXfRecord.getConsTime() != null) {
            strDate = DateUtils.getStrDate(entityXfRecord.getConsTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
        }

        if (entityXfRecord.getMealNo().equals("500")) {
            //餐段按天
//            queryWrapper.last("and TO_DAYS(create_time) = TO_DAYS('"+strDate+"')");
            strDate = strDate.substring(0, 10);
//            queryWrapper.between( "create_time",strDate+" 00:00:00",strDate+" 23:59:59");
            queryWrapper.eq(EntityXfRecordProcessExxx::getMealDate, strDate);
        } else if (entityXfRecord.getMealNo().equals("1000")) {
            //按月查询
//            queryWrapper.last("and DATE_FORMAT(create_time,'%Y%m') = DATE_FORMAT('"+strDate+"','%Y%m')");
//            strDate = strDate.substring(0, 7).replace("-", "");
//            queryWrapper.apply(" DATE_FORMAT(meal_date, '%Y%m') =" + strDate);
            strDate = strDate.substring(0, 7);
            String endDate = DateUtils.getLastDayOfMonth(Integer.valueOf(strDate.substring(5)));
            queryWrapper.between(EntityXfRecordProcessExxx::getMealDate, strDate + "-01", endDate);
        } else {
            queryWrapper.eq(EntityXfRecordProcessExxx::getMealNo, entityXfRecord.getMealNo());
//            queryWrapper.last("and TO_DAYS(create_time) = TO_DAYS('"+strDate+"')");
            strDate = strDate.substring(0, 10);
            queryWrapper.eq(EntityXfRecordProcessExxx::getMealDate, strDate);
//            queryWrapper.between( "create_time",strDate+" 00:00:00",strDate+" 23:59:59");
        }

        queryWrapper.notDefaultSelectAll().leftJoin(EntityXfRecordProcessExtend.class, EntityXfRecordProcessExtend::getOrderId, EntityXfRecordProcessExxx::getId)
                .select(EntityXfRecordProcessExtend::getCancelState).selectAs((cb) -> {
                    cb.add(" count(*) ","times",false);
                    cb.add(" sum(real_money) ","amount",false); // 这个为false就是代表不是字符串，会原样查询 在1.3.1版本后支持
                }).apply("( xf_record_process_extend.cancel_state = 0 or  xf_record_process_extend.cancel_state is null  ) ").end();

        return this.joinGetOne(queryWrapper,TimesAmountVoExxx.class);
    }


    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public List<EntityXfRecordProcessExxx> getRefunding(Long companyId) {
        JoinLambdaWrapper<EntityXfRecordProcessExxx> queryWrapper = new JoinLambdaWrapper<>(EntityXfRecordProcessExxx.class);
        queryWrapper.in(EntityXfRecordProcessExxx::getConsState, 1, 3, 5);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPayState, 1);
        queryWrapper.eq(EntityXfRecordProcessExxx::getIfRefund, 0);
        queryWrapper.gt(EntityXfRecordProcessExxx::getCreateTime, DateUtil.getDateBefore(new Date(),3));
        queryWrapper.orderByDesc(EntityXfRecordProcessExxx::getId);

        queryWrapper.leftJoin(EntityXfRecordProcessExtend.class, EntityXfRecordProcessExtend::getOrderId, EntityXfRecordProcessExxx::getId)
                .select(EntityXfRecordProcessExtend::getCancelState).apply(" xf_record_process_extend.cancel_state > 0 and   xf_record_process_extend.cancel_state < 203  ").end();

        return this.joinList(queryWrapper,EntityXfRecordProcessExxx.class);
    }


    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public List<EntityXfRecordProcessExxx> getUserOrders(Long companyId, UserOrdersQueryVo queryVo) {
        JoinLambdaWrapper<EntityXfRecordProcessExxx> queryWrapper = new JoinLambdaWrapper<>(EntityXfRecordProcessExxx.class);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPId, queryVo.getPId());
        queryWrapper.eq(EntityXfRecordProcessExxx::getComId, queryVo.getComId());
        queryWrapper.in(EntityXfRecordProcessExxx::getConsState, 1, 3, 5);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPayState, 1);
        queryWrapper.eq(EntityXfRecordProcessExxx::getIfRefund, 0);
        queryWrapper.eq(EntityXfRecordProcessExxx::getConsType, queryVo.getConsType());

        queryWrapper.between(EntityXfRecordProcessExxx::getMealDate, queryVo.getStartDate(),queryVo.getEndDate());

        queryWrapper.leftJoin(EntityXfRecordProcessExtend.class, EntityXfRecordProcessExtend::getOrderId, EntityXfRecordProcessExxx::getId)
                .select(EntityXfRecordProcessExtend::getCancelState).end();
        return this.joinList(queryWrapper,EntityXfRecordProcessExxx.class);

    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    public EntityXfRecordProcessExxx selectTradeNo(Long companyId, String tradeNo, String machNo) {
        JoinLambdaWrapper<EntityXfRecordProcessExxx> queryWrapper = new JoinLambdaWrapper<>(EntityXfRecordProcessExxx.class);
        queryWrapper.eq(EntityXfRecordProcessExxx::getComId, companyId);
        if (!CommonUtil.isNull(machNo)) {
            queryWrapper.eq(EntityXfRecordProcessExxx::getDeviceNo, machNo);
        }
        queryWrapper.in(EntityXfRecordProcessExxx::getOrderNo, tradeNo, "DK" + tradeNo, "LX" + tradeNo);
        queryWrapper.orderByDesc(EntityXfRecordProcessExxx::getId);
        queryWrapper.last("limit 1");
        queryWrapper.leftJoin(EntityXfRecordProcessExtend.class, EntityXfRecordProcessExtend::getOrderId, EntityXfRecordProcessExxx::getId)
                .select(EntityXfRecordProcessExtend::getCancelState, EntityXfRecordProcessExtend::getReceiptPrice).end();
        return this.joinGetOne(queryWrapper, EntityXfRecordProcessExxx.class);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public EntityXfRecordProcessExxx selectTradeNo(Long companyId, Long id) {
        JoinLambdaWrapper<EntityXfRecordProcessExxx> queryWrapper = new JoinLambdaWrapper<>(EntityXfRecordProcessExxx.class);
        queryWrapper.eq(EntityXfRecordProcessExxx::getComId, companyId);
        queryWrapper.eq(EntityXfRecordProcessExxx::getId, id);
        queryWrapper.leftJoin(EntityXfRecordProcessExtend.class, EntityXfRecordProcessExtend::getOrderId, EntityXfRecordProcessExxx::getId)
                .select(EntityXfRecordProcessExtend::getCancelState,EntityXfRecordProcessExtend::getReceiptPrice).end();
        return this.joinGetOne(queryWrapper,EntityXfRecordProcessExxx.class);
    }


    //第一医院分院
    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public int getUserPartCityCount(Long companyId, Date mealDate, Long pId) {
        JoinLambdaWrapper<EntityXfRecordProcessExxx> queryWrapper = new JoinLambdaWrapper<>(EntityXfRecordProcessExxx.class);
        queryWrapper.eq(EntityXfRecordProcessExxx::getComId, 693);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPId, pId);
        queryWrapper.in(EntityXfRecordProcessExxx::getMealNo, 2,3);
        String date = DateUtils.getStrDate(mealDate, "yyyy-MM-dd");
        queryWrapper.eq(EntityXfRecordProcessExxx::getMealDate, date );
        queryWrapper.eq(EntityXfRecordProcessExxx::getConsType, 1 );
        queryWrapper.in(EntityXfRecordProcessExxx::getConsState, 1,3,5);
        queryWrapper.eq(EntityXfRecordProcessExxx::getPayState, 1);
        queryWrapper.eq(EntityXfRecordProcessExxx::getIfRefund, 0);
        queryWrapper.leftJoin(EntityXfRecordProcessExtend.class, EntityXfRecordProcessExtend::getOrderId, EntityXfRecordProcessExxx::getId)
                .apply("( xf_record_process_extend.cancel_state = 0 or  xf_record_process_extend.cancel_state is null  ) ").end();
        return this.joinCount(queryWrapper);
    }




    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public List<EntityXfRecordProcessExxx> selectRefundRecodes(Long companyId, String tradeNo) {
        return this.list(Wrappers.lambdaQuery(EntityXfRecordProcessExxx.class).eq(EntityXfRecordProcessExxx::getOrigOrderNo,tradeNo).eq(EntityXfRecordProcessExxx::getComId,companyId));
    }
}

